package com.yzqp.common.mvc.base;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yzqp.common.exception.GlobalRuntimeException;
import com.yzqp.common.util.BeanUtil;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Data
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class BaseService<D extends BaseDao, T extends BaseBean> {


    @Autowired
    protected D _baseDao;

    /**
     * 保存数据（插入或更新）
     * 注意：entity 属性为 null 时, 不参与sql执行
     *
     * @param entity
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    protected T save(T entity) {
        if (entity == null) {
            throw new GlobalRuntimeException("请传入正确的参数");
        }
        //id为空，新增
        if (entity.getId() == null) {
            entity.preInsert();
            _baseDao.insert(entity);
            return entity;
        }
        //保存
        _baseDao.updateById(entity);
        return entity;
    }

    /**
     * 新增
     *
     * @param entity
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public T insert(T entity) {
        if (entity == null) {
            throw new GlobalRuntimeException("请传入正确的参数");
        }
        entity.preInsert();
        _baseDao.insert(entity);
        return entity;
    }

    /**
     * 逻辑删除
     *
     * @param id
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void deleteById(Long id) {
        T item = get(id);
        if (item == null) {
            throw new GlobalRuntimeException("找不到目标实体");
        }
        item.setDeleteFlag(true);
        LambdaUpdateWrapper<T> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(T::getId, id);
        updateWrapper.set(T::getCreateBy, "333");
        _baseDao.update(null, updateWrapper);
    }


    /**
     * 物理删除
     *
     * @param id
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void physicsDeleteById(Long id) {
        T t = this.get(id);
        if (t == null) {
            throw new GlobalRuntimeException("找不到目标实体,无法删除");
        }
        _baseDao.deleteById(id);
    }

    /**
     * 修改不为空的数据
     *
     * @param entity
     * @return
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public T update(T entity) {
        if (entity == null) {
            throw new GlobalRuntimeException("请传入参数");
        }
        T item = this.get(entity.getId());
        if (item == null) {
            throw new GlobalRuntimeException("找不到目标实体");
        }
        BeanUtil.copyProperties(item, entity);
        _baseDao.updateById(item);
        return item;
    }

    /**
     * 通过id查询数据
     *
     * @param id
     * @return
     */
    public T get(Long id) {
        T t = (T) _baseDao.selectById(id);
        if (t == null) {
            return null;
        }
        //如果已经逻辑删除的话
        if (t.getDeleteFlag()) {
            return null;
        }
        return t;
    }


    /**
     * 条件查询全部数据
     *
     * @return
     */
    public List<T> findAllList() {
        return _baseDao.selectList(new QueryWrapper());
    }

    /**
     * 条件查询分页
     *
     * @param current
     * @param size
     * @return
     */
    public IPage<T> findSinglePage(T entity, int current, int size) {
        IPage<T> page = new Page<>(current, size);
//        page = _mapper.selectPage(page, new QueryWrapper());
        page = _baseDao.findPage(page, entity);
        return page;
    }
}
